home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
United Public Domain Gold 2
/
United Public Domain Gold 2.iso
/
education
/
pe023.dms
/
pe023.adf
/
ALGORHYTHMS
/
SOURCE
/
ALGORHYTHMS.C
next >
Wrap
C/C++ Source or Header
|
1988-10-05
|
21KB
|
741 lines
/*AlgoRhythms.c*/
/*Thomas E. Janzen 4 September 1989; 2-11-90 */
/*18 September 1989 26 nov 89 11 December 1989 16 December 1989*/
/*Music played with this program Copyright 1990 Thomas E. Janzen */
/*This program Copyright 1990 Thomas E. Janzen All Rights Reserved */
/*This program is for a Commodore (TM) Amiga (TM) 500 playing MIDI */
/*Lattice C 5.05*/
/*out the serial port to a single MIDI channel with MAXVOICE voices */
/*The music is randomized by changes slowly by sinusoidal functions */
/*
** FACILITY:
**
** AlgoRhythms music improviser on Commodore (TM) Amiga (TM)
** compiled with Lattice (TM) C 5.05
**
** ABSTRACT:
**
** Algorhythms improvises music over the MIDI serial port.
** See the manual.
**
** AUTHOR: Thomas E. Janzen
**
** CREATION DATE: 26-MAR-1990
**
** MODIFICATION HISTORY:
** DATE NAME DESCRIPTION
**--
*/
#define TWOPI (2 * PI)
#define DURMAX 2.0
#define PROJECT (0)
#define FORM (1)
#define SCALE (2)
#define CHANNEL (3)
#include "limits.h"
#include "math.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "intuition/intuition.h"
#include "exec/memory.h"
#include "exec/interrupts.h"
#include "exec/devices.h"
#include "devices/serial.h"
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/exec.h>
#include <proto/mathffp.h>
#include <proto/intuition.h>
#include "Workbench/startup.h"
#define STRINGSIZE 80
#include "musictimer.h"
#include "window.h"
extern struct Window *w;
#include "musicserial.h"
#include "Gadgets.h"
struct Parameter Randomize_Parameter(void);
#include "files.h"
#include "DrawForm.h"
extern struct GfxBase *GfxBase;
extern struct IntuitionBase *IntuitionBase;
extern struct DOSBase *DOSBase;
extern struct MathBase *MathBase;
void MakeEvent(struct NoteEvent *, struct Character *,
const double CurTime); /* Calculates the next note to send out */
struct Parameter {
double CenterCycle;
double CenterPhase;
double SpreadCycle;
double SpreadPhase;
};
int fubar=FALSE;
static struct Parameter Pitch_Form = {180.0,-PID2,200.0,-PID2};
static struct Parameter Thickness_Form = {0.0, 0.0,190.0,-PID2};
static struct Parameter Dynamics_Form = {170.0,-PID2,165 ,-PID2};
static struct Parameter Duration_Form = {200.0, PID2,180.0, PID2};
struct Character {
double PitchSpread; /*range of pitches*/
double PitchCenter; /* ~ median pitch*/
double DynamicSpread; /*range of dynamic levels*/
double DynamicCenter; /* ~ median of dynamic levels*/
double DurSpread; /*range of durations */
double DurCenter; /* ~ median of durations */
double Thickness; /*number of voices playing at once*/
};
struct Character *ranges(
struct Parameter *Pitch,
struct Parameter *Dyn,
struct Parameter *Dur,
struct Parameter *Thickness,
const double phase);
int EventPointer = 0;
/*Pitch Range*/
int range=10;
int halfrange=5;
#include "scales.h"
#include "menus.h"
int ParseMessage(int class, int code, double *StrTime,
struct Parameter *PitchForm, struct Parameter *RhythmForm,
struct Parameter *DynamicsForm, struct Parameter *TextureForm,
double *Duration,int *tempo, struct NoteEvent *Events);
int scale[120] = {48,50,53,55,58,60,62,65,67,70,72,74,77};
/* holds the scale of notes allowed */
static int numvoices=MAXVOICE;
static struct timeval timval;
int playing = FALSE; /* playing music */
int started= FALSE;
int done=FALSE;
int quit=FALSE;
int DelayTicks = 2;
double MaxNoteLen = 2.0;
double MinNoteLen = 0.0;
double NoteLenDif = 2.0;
void main(void)
{
register int tick=0;
int code, class; /* mouse codes esp. for menus */
int Action=0;
register double CurTime; /*the current time in seconds*/
double PieceDuration=600.0; /*piece length in seconds*/
int tempo;
static struct NoteEvent Events[MAXVOICE];
register int temptv_secs;
register int temptv_micro;
static struct Character Now;
int i;
static double StartTime=0.0;/*time that the program starts to execute*/
register double phase;
MakeWindow();
Open_MIDI_Port();
if(fubar == TRUE) goto cleanup2;
Init_Menu(); /*menu*/
tempo=50/DelayTicks;
range=InstallScale(11,scale);
halfrange=range/2;
for (i=0;i<MAXVOICE;i++) {
Events[i].Pitch=halfrange;
Events[i].Dynamic=0.0;
Events[i].StartTime=0.0;
Events[i].Duration=0.0;
Events[i].Channel=0;
Events[i].CurPitch=60;
Events[i].LowPitch=24;
Events[i].HighPitch=108;
Events[i].Walking=FALSE;
}
/*set the form of the piece*/
StartTimer();
GetSysTime(&timval);
temptv_secs = (int)timval.tv_secs;
temptv_micro= (int)timval.tv_micro;
srand(temptv_micro);
StartTime=(double)temptv_secs+(((double)temptv_micro)*0.000001);
/*Save Time the program started*/
CurTime=0.0;
GetSysTime(&timval);
StartTime=
(double)timval.tv_secs+(((double)timval.tv_micro)*0.000001);
/*Save Time the program started*/
phase=TWOPI*CurTime;
Pitch_Form=Randomize_Parameter();
Duration_Form=Randomize_Parameter();
Dynamics_Form=Randomize_Parameter();
Thickness_Form=Randomize_Parameter();
DrawForm(PieceDuration,&Pitch_Form,&Duration_Form,
&Dynamics_Form,&Thickness_Form);
Now = *ranges(&Pitch_Form,&Dynamics_Form,
&Duration_Form,&Thickness_Form, phase);
/*Initialize the ranges (pitch, dynamic, duration)*/
/*Master Control Loop*/
while(!(quit)) {
GetSysTime(&timval);
CurTime=(double)timval.tv_secs +
(((double)timval.tv_micro)*0.000001)-StartTime;
while (playing = (!(done) && started) && !(quit)) {
GetSysTime(&timval);
CurTime=(double)timval.tv_secs +
(((double)timval.tv_micro)*0.000001)-StartTime;
phase = TWOPI * CurTime;
Now = *ranges(&Pitch_Form,&Dynamics_Form,
&Duration_Form,&Thickness_Form, phase);
for (EventPointer=0;EventPointer < numvoices;
EventPointer++) {
if((CurTime-Events[EventPointer].StartTime)
> Events[EventPointer].Duration) {
MakeEvent(&Events[EventPointer],
&Now, CurTime);
}
}
DrawTime(CurTime,PieceDuration);
if (Action=CheckMenu(&class, &code)) {
ParseMessage(class,code,&StartTime,
&Pitch_Form,&Duration_Form,&Dynamics_Form,
&Thickness_Form,&PieceDuration,&tempo,
Events);
}
if (DelayTicks) {
for(tick=0;tick<DelayTicks;tick=tick+2) {
SendFunction(CLOCKFUNCT);
Delay(2);/*give music a pulse*/
}
}
if(done=(CurTime > PieceDuration)) {
StopAllNotes(Events);
started=FALSE;
}
}
Wait(1 << w->UserPort->mp_SigBit);
if (Action=CheckMenu(&class, &code)) {
ParseMessage(class,code,&StartTime,
&Pitch_Form,&Duration_Form,&Dynamics_Form,
&Thickness_Form,&PieceDuration,&tempo,Events);
}
continue;
}
cleanup1:
CloseMenu();
StopAllNotes(Events);
Delay(10);
RemoveTimer();
cleanup2: /* exit here if the serial port wouldn't open*/
ShutWindow();
StopMIDI();
exit(0);
} /* end main*/
struct Character *ranges(
struct Parameter *Pitch,
struct Parameter *Dyn,
struct Parameter *Dur,
struct Parameter *Thickness,
const double phase)
{
static struct Character NextNow;
register double realhalfrange;
realhalfrange=(double)halfrange;
NextNow.PitchSpread=(sin((phase/Pitch->SpreadCycle)+
Pitch->SpreadPhase)+1.0)*
realhalfrange;
/*Pitch range is a sin function of time*/
NextNow.PitchCenter=(sin((phase/(Pitch->CenterCycle))+
(Pitch->CenterPhase))+1.0)*
realhalfrange;
/*Median Pitch is a sin funct of time*/
if((NextNow.PitchCenter - (NextNow.PitchSpread/2)) < 0) {
NextNow.PitchCenter = 1.0 + ((NextNow.PitchCenter+
(NextNow.PitchSpread/2))/2);
}
else {
if((NextNow.PitchCenter+(NextNow.PitchSpread/2)) >
(double)range) {
NextNow.PitchCenter = realhalfrange - 1.0 +
((NextNow.PitchCenter - (NextNow.PitchSpread/2.0))
/2.0);
}
}
NextNow.DynamicSpread=(sin((phase/(Dyn->SpreadCycle))+
Dyn->SpreadPhase)+1.01)*63;
/*Range of dynamics is a sin function of time*/
NextNow.DynamicCenter=((sin((phase/(Dyn->CenterCycle))+
Dyn->CenterPhase)+1.01)* 50) + 25;
/*Median dynamic is a sin function of time*/
NextNow.DurSpread=(sin((phase/(Dur->SpreadCycle))+
Dur->SpreadPhase)+1.01)*NoteLenDif;
/* Range of durations is a sin function of time*/
NextNow.DurCenter=((sin((phase/(Dur->CenterCycle))+
Dur->CenterPhase)+1.01)*NoteLenDif)+MinNoteLen;
/*Median duration is a sin function of time*/
NextNow.Thickness=((sin((phase/(Thickness->SpreadCycle))+
Thickness->SpreadPhase)+1.01)*(double)numvoices/2.0)-1.0;
/*the number of voices playing is a sin function of time*/
return &NextNow;
}
struct Parameter Randomize_Parameter(void)
{
struct Parameter Temp;
register double reallong_max;
reallong_max=(double)LONG_MAX;
Temp.CenterCycle=((double)rand()/reallong_max)*(120)+90;
/*1.5 to 3.5 minutes */
Temp.CenterPhase=((double)rand()/reallong_max)*TWOPI;
Temp.SpreadCycle=((double)rand()/reallong_max)*(120)+90;
/*1.5 to 3.5 minutes */
Temp.SpreadPhase=((double)rand()/reallong_max)*TWOPI;
return Temp;
}
void MakeEvent(struct NoteEvent *NewEvent,
struct Character *Style, const double CurTime) {
int LowNote;
int HighNote;
int OKRandNote;
int walk;
register double reallong_max;
register double reallong_maxdiv2;
double NewDynamic; /*a temporary holder of a new dynamic value*/
double NewDuration; /*a temporary holder of a new duration value*/
int NewPitchIndex;
OKRandNote=TRUE;
reallong_max=(double)LONG_MAX;
reallong_maxdiv2=reallong_max/2.0;
PlayNoteOff(NewEvent);
/*Turn off the previous note*/
/*for this voice*/
if (EventPointer<=(int)(Style->Thickness)) {
NewDynamic= ((((double)rand()/reallong_maxdiv2))-1.0)
*(Style->DynamicSpread)+(Style->DynamicCenter);
/*get random dynamic*/
if (NewDynamic > 127){ /*compress dynamic to be valid*/
NewDynamic=127;
}
if (NewDynamic < 0 ) { /*compress dynamic to be valid*/
NewDynamic=0;
}
NewEvent->Dynamic=(int)NewDynamic;/* make dynamic a byte*/
NewDuration=((((double)rand()/reallong_maxdiv2))-1.0)
* (Style->DurSpread)+(Style->DurCenter) +
((Style->DurSpread)/8);
/*Get random duration*/
if (NewDuration<0.0) { /*force duration positive*/
NewDuration = 0;
}
NewEvent->Duration=NewDuration; /*Put duration in */
/* durations list */
NewEvent->StartTime=CurTime;
/*Make attacktime for this note */
/* equal to current time */
/*PITCH*/
if(NewEvent->Walking) {
HighNote=
((NewEvent->CurPitch) >= NewEvent->HighPitch);
LowNote=
((NewEvent->CurPitch) <= NewEvent->LowPitch);
walk = (rand() % 3)-1;
if(LowNote) {
walk=1;
}
if(HighNote) {
walk=-1;
}
NewPitchIndex=(NewEvent->Pitch)+walk;
}
else {
NewPitchIndex=
((((double)rand()/reallong_maxdiv2))-1.0)
* (Style->PitchSpread)+(Style->PitchCenter);
HighNote=
((scale[NewPitchIndex]) >= NewEvent->HighPitch);
LowNote=
((scale[NewPitchIndex]) <= NewEvent->LowPitch);
OKRandNote=(!(HighNote) && (!(LowNote)));
}
if (NewPitchIndex >= range) {
NewPitchIndex=range-1;
/*fold under if too hi*/
}
if (NewPitchIndex < 0) {
/*fold up if too low */
NewPitchIndex = 0;
}
NewEvent->Pitch=(int)NewPitchIndex; /*pitch in note list*/
NewEvent->CurPitch=scale[(int)NewPitchIndex];
/*Play the note*/
if (playing && OKRandNote)PlayNoteOn(NewEvent);
}
}
int ParseMessage(int class, int code, double *StrTime,
struct Parameter *PitchForm, struct Parameter *RhythmForm,
struct Parameter *DynamicsForm, struct Parameter *TextureForm,
double *Duration,int *tempo, struct NoteEvent Events[MAXVOICE]
) {
int i;
int tempint;
int Status; /* file status */
extern int midi_addr;
int item=0; int subitem=0;
static double StopTime, ContTime;
static char AnswerBuf[96];
static char FileString[64]={0,0,0,0,0,0,0,0,0};
char *AnsBuf;
static char FileNameString[] = "File Name";
static char DurationString[]="Duration in Seconds";
static char PaceString[]="Rhythmic Pace";
static char DynamicString[]="Dynamics";
static char TextureString[]="Texture";
static char PitchString[]="Pitch";
static char DynamicMean[]="Dynamic Mean";
static char DynamicSpread[]="Dynamic Spread";
static char TextureSpread[]="Texture Spread";
static char PitchMean[]="Pitch Mean";
static char PitchSpread[]="Pitch Spread";
static char RhythmMean[]="Rhythm Mean";
static char RhythmSpread[]="Rhythm Spread";
static char VoiceString[]="Number of Voices";
static char BlankString[4]=" ";
static char SpreadPeriodString[]="Spread Period";
static char MeanPeriodString[]="Mean Period";
static char PulseString[]="Pulses per Second";
static char TransposeString[]="Tranpose";
static char LoadFileString[]="Load File";
static char SaveFileString[]="Save File";
static char NoteLenString[]="Note Length";
static char MinimumString[]="Minimum";
static char MaximumString[]="Maximum";
static char About1String[24]=
"Welcome to AlgoRhythms";
static struct IntuiText About1Txt=
{2,1,JAM1,5,4,NULL,About1String,NULL};
static char About2String[32]=
"Copyright 1990 Thomas E. Janzen";
static struct IntuiText About2Txt=
{2,1,JAM1,5,15,NULL,About2String,&About1Txt};
static char ThanksString[]="Thanks";
struct IntuiText ThanksTxt={2,1,JAM1,5,4,NULL,ThanksString,
NULL};
int Response;
switch(class) {
case NEWSIZE:
DrawForm(*Duration,PitchForm,RhythmForm,
DynamicsForm,TextureForm);
break;
case MENUPICK:
if (code != MENUNULL) {
item=ITEMNUM(code);
subitem=SUBNUM(code);
switch(MENUNUM(code)) {
case PROJECT:
if (item != NOITEM) switch(item) {
case 0: /*quit*/
quit=TRUE;
break;
case 1: /*About*/
Response=AutoRequest(w,&About2Txt,&ThanksTxt,&ThanksTxt,
0L,0L,300L,60L);
break;
case 2: /*save*/
sprintf(AnswerBuf,"%s",FileString);
Status=GetStringInput(AnswerBuf,SaveFileString,
FileNameString);
if (Status == 1) break;
Status=Save_File(AnswerBuf,Duration,&range,scale,
&numvoices,tempo,PitchForm,TextureForm,DynamicsForm,
RhythmForm,Events,MinNoteLen,MaxNoteLen);
if (Status == 0) {
__builtin_strcpy(FileString,AnswerBuf);
}
else {
DisplayBeep(NULL);
}
break;
case 3: /*load*/
sprintf(AnswerBuf,"%s",FileString);
Status=GetStringInput(AnswerBuf,LoadFileString,
FileNameString);
if (Status == 1) break;
Status=Read_File(AnswerBuf,Duration,
&range,scale,&numvoices,tempo,PitchForm,
TextureForm,DynamicsForm,RhythmForm,Events,
&MinNoteLen,&MaxNoteLen);
if (Status == 0) {
if (*tempo == 0) {
DelayTicks=0;
}
else {
DelayTicks=50/(*tempo);
}
halfrange=range/2;
__builtin_strcpy(FileString,AnswerBuf);
DrawForm(*Duration,PitchForm,RhythmForm,
DynamicsForm,TextureForm);
}
else {
DisplayBeep(NULL);
}
break;
case 4: /* Continue */
started=TRUE;
GetSysTime(&timval);
ContTime=(double)timval.tv_secs+
(((double)timval.tv_micro)*0.000001);
*StrTime=*StrTime+(ContTime-StopTime);
break;
case 5: /*stop*/
started=FALSE;
for (i=0;i<MAXVOICE;i++) {
(&Events[i])->StartTime=0.0;
(&Events[i])->Duration=0.0;
}
StopAllNotes(Events);
GetSysTime(&timval);
StopTime=(double)timval.tv_secs+
(((double)timval.tv_micro)*0.000001);
break;
case 6: /*Start to Play*/
started=TRUE;
done=FALSE;
GetSysTime(&timval);
*StrTime=(double)timval.tv_secs+
(((double)timval.tv_micro)*0.000001);
for (i=0;i<MAXVOICE;i++) {
(&Events[i])->StartTime=0.0;
(&Events[i])->Duration=0.0;
}
SendFunction(STARTFUNCT);
break;
} /*switch itemnum*/
break;
case FORM:
if (item != NOITEM) switch(item) {
case 0: /*note length*/
if (subitem != NOSUB) switch(subitem) {
case 0: /*minimum*/
sprintf(AnswerBuf,"%5.2f",MinNoteLen);
AnsBuf=GetGadgetInput(AnswerBuf,
NoteLenString,MinimumString);
MinNoteLen=atof(AnsBuf);
NoteLenDif=MaxNoteLen-MinNoteLen;
break;
case 1: /*maximum*/
sprintf(AnswerBuf,"%5.2f",MaxNoteLen);
AnsBuf=GetGadgetInput(AnswerBuf,
NoteLenString,MaximumString);
MaxNoteLen=atof(AnsBuf);
NoteLenDif=MaxNoteLen-MinNoteLen;
break;
}
break;
case 1: /*Texture*/
if (subitem != NOSUB) switch(subitem) {
case 0: /* Randomize */
*TextureForm=Randomize_Parameter();
break;
case 1: /*Spread Period*/
sprintf(AnswerBuf,"%2.0f",(TextureForm->SpreadCycle));
AnsBuf=GetGadgetInput(AnswerBuf,
TextureString,SpreadPeriodString);
TextureForm->SpreadCycle=atof(AnsBuf);
break;
case 2: /*Spread Phase*/
TextureForm->SpreadPhase=
GetPhaseInput(TextureForm->SpreadPhase,TextureSpread);
break;
}
break;
case 2: /*Dynamic*/
if (subitem != NOSUB) switch(subitem) {
case 0: /* Randomize */
*DynamicsForm=Randomize_Parameter();
break;
case 1: /* Spread Phase*/
DynamicsForm->SpreadPhase=
GetPhaseInput(DynamicsForm->SpreadPhase,DynamicSpread);
break;
case 2: /* Spread Period*/
sprintf(AnswerBuf,"%2.0f",DynamicsForm->SpreadCycle);
AnsBuf=GetGadgetInput(AnswerBuf,
DynamicString,SpreadPeriodString);
DynamicsForm->SpreadCycle=atof(AnsBuf);
break;
case 3: /* mean Phase*/
DynamicsForm->CenterPhase=
GetPhaseInput(DynamicsForm->CenterPhase,DynamicMean);
break;
case 4: /* Mean Period*/
sprintf(AnswerBuf,"%2.0f",DynamicsForm->CenterCycle);
AnsBuf=GetGadgetInput(AnswerBuf,
DynamicString,MeanPeriodString);
DynamicsForm->CenterCycle=atof(AnsBuf);
break;
}
break;
case 3: /*Rhythm*/
if (subitem != NOSUB) switch(subitem) {
case 0: /* Randomize */
*RhythmForm=Randomize_Parameter();
break;
case 1: /* Spread Phase*/
RhythmForm->SpreadPhase=
GetPhaseInput(RhythmForm->SpreadPhase,RhythmSpread);
break;
case 2: /* Spread Period*/
sprintf(AnswerBuf,"%2.0f",RhythmForm->SpreadCycle);
AnsBuf=GetGadgetInput(AnswerBuf,
PaceString,SpreadPeriodString);
RhythmForm->SpreadCycle=atof(AnsBuf);
break;
case 3: /* mean Phase*/
RhythmForm->CenterPhase=
GetPhaseInput(RhythmForm->CenterPhase,RhythmMean);
break;
case 4: /* Mean Period*/
sprintf(AnswerBuf,"%2.0f",RhythmForm->CenterCycle);
AnsBuf=GetGadgetInput(AnswerBuf,
PaceString,MeanPeriodString);
RhythmForm->CenterCycle=atof(AnsBuf);
break;
}
break;
case 4: /*Pitch*/
if (subitem != NOSUB) switch(subitem) {
case 0: /* Randomize */
*PitchForm=Randomize_Parameter();
break;
case 1: /* Spread Phase*/
PitchForm->SpreadPhase=
GetPhaseInput(PitchForm->SpreadPhase,
PitchSpread);
break;
case 2: /* Spread Period*/
sprintf(AnswerBuf,"%2.0f",PitchForm->SpreadCycle);
AnsBuf=GetGadgetInput(AnswerBuf,
PitchString,SpreadPeriodString);
PitchForm->SpreadCycle=atof(AnsBuf);
break;
case 3: /* mean Phase*/
PitchForm->CenterPhase=
GetPhaseInput(PitchForm->CenterPhase,PitchMean);
break;
case 4: /* Mean Period*/
sprintf(AnswerBuf,"%2.0f",PitchForm->CenterCycle);
AnsBuf=GetGadgetInput(AnswerBuf,
PitchString,MeanPeriodString);
PitchForm->CenterCycle=atof(AnsBuf);
break;
}
break;
case 5: /*Duration*/
sprintf(AnswerBuf,"%2.0f",*Duration);
AnsBuf=GetGadgetInput(AnswerBuf,
BlankString,DurationString);
*Duration=atof(AnsBuf);
break;
case 6: /*pulse*/
sprintf(AnswerBuf,"%d",*tempo);
AnsBuf=GetGadgetInput(AnswerBuf,
BlankString,PulseString);
*tempo=abs(atoi(AnsBuf));
if (*tempo == 0) {
DelayTicks=0;
}
else {
DelayTicks=50/(*tempo);
}
break;
case 7: /*ReDraw*/
DrawForm(*Duration,PitchForm,RhythmForm,
DynamicsForm,TextureForm);
break;
case 8: /*numvoices*/
sprintf(AnswerBuf,"%d",numvoices);
AnsBuf=GetGadgetInput(AnswerBuf,
BlankString,VoiceString);
tempint=atoi(AnsBuf);
if((tempint <= MAXVOICE)&&(tempint > 0)) {
numvoices=tempint;
}
else {
DisplayBeep(NULL);
}
break;
} /*switch itemnum*/
break;
case SCALE:
if (item != NOITEM) switch(item) {
case 0: /*transpose*/
sprintf(AnswerBuf,"0");
AnsBuf=GetGadgetInput(AnswerBuf,
BlankString,TransposeString);
TransposeScale(atoi(AnsBuf),scale,range);
break;
default:
range=InstallScale(12-item,scale);
halfrange=range/2;
} /*switch itemnum*/
break;
case CHANNEL:
GetChannelStuff(&Events[item],item);
break;
} /*switch menunum*/
} /*while menunull*/
break;
case CLOSEWINDOW:
quit=TRUE;
break;
} /*switch class*/
return (0);
} /*end function*/